Subject: Re: Using Display Database
From: [email-masked] (Michael B. Smith)
Date: Mon, 10 Jan 94 22:14:00 EDT
Newsgroups: comp.sys.amiga.programmer

In article <[email-masked]> [email-masked] (Dimitri Favre) writes:
> I'm developping a tool and I need to allow user to use whatever screen
> it wants. I'm searching a demo code showing how to use the display database
> (I mean, the Monitors in Devs:Monitors) to implement a WorkBench like
> screen Requester (even through GadToolBox).

Here is some example code from GRn. It compiles with commercial and
registered DICE; but should be trivial to modify for SAS/C. It DOES
require asl.library v38 or higher. Regardless, you can take the
information from ModeSize() and FitWB() and come up with routines
that should work on v37 as well.
--
  //   Michael B. Smith
\X/    [email-masked]  -or-  uunet.uu.net!virginia.edu!adastra!mbs

static ULONG
ModeSize (ULONG modeID, int *x, int *y)
{
	/*
	**  ModeSize
	**
	**	Returns the size of the passed ModeID.
	**	The 'X' and 'Y' sizes are stored in the parameters.
	**
	**	On failure, returns INVALID_ID.
	**	On success, returns modeID.
	*/
	struct DimensionInfo
		di;

	if (GetDisplayInfoData (NULL, (void *) &di, sizeof di, DTAG_DIMS, modeID)) {
		*x = di.TxtOScan.MaxX - di.TxtOScan.MinX + 1;
		*y = di.TxtOScan.MaxY - di.TxtOScan.MinY + 1;
		return modeID;
	}

	return INVALID_ID;
}

static ULONG
FitWB (int *x, int *y)
{
	/*
	**  FitWB:   returns the modeID which "first fits" the passed X and
	**	     Y parameters, and is suitable for a Workbench screen.
	**
	**  On failure, returns INVALID_ID.
	*/

	ULONG
		modeID = INVALID_ID;
	int
		X = 0,
		Y = 0;
	struct DisplayInfo
		ds;

	while ((modeID = NextDisplayInfo (modeID)) != INVALID_ID) {

		if (ModeNotAvailable (modeID))
			continue;

		if ((modeID & MONITOR_ID_MASK) == DEFAULT_MONITOR_ID)
			continue;

		if (GetDisplayInfoData (NULL, (void *) &ds, sizeof (struct DisplayInfo), DTAG_DISP, modeID))
			if (!(ds.PropertyFlags & DIPF_IS_WB))
				continue;

		if (ModeSize (modeID, &X, &Y) != INVALID_ID) {
			if (X >= *x && Y >= *y) {
				*x = X;
				*y = Y;
				return modeID;
			}
		}
	}

	return INVALID_ID;
}

#define MINIMUM_HEIGHT	    200
#define MINIMUM_WIDTH	    600

__geta4 __asm ULONG
ScreenModeHook (__a0 struct Hook *myhook,
		__a2 struct ScreenModeRequester *myScreenReq,
		__a1 APTR data)
{
	ULONG
		modeID = (ULONG) data;
	int
		x,
		y;

	if (ModeNotAvailable (modeID))
		return FALSE;

	if (ModeSize (modeID, &x, &y) == INVALID_ID)
		return FALSE;

	if (x < MINIMUM_WIDTH || y < MINIMUM_HEIGHT)
		return FALSE;

	return TRUE;
}

int
GetScreenMode (ULONG *modeID, int *height, int *width, int *autoscroll)
{
	int
		rslt,
		mode_width  = *width ? *width : DEFAULT_WIDTH,
		mode_height = *height ? *height : DEFAULT_HEIGHT;
	ULONG
		pref_mode = FitWB (&mode_width, &mode_height);
	struct Hook
		ScreenReqHook;
	struct ScreenModeRequester
		*screenReq;
	static const char
		routine [] = { "GRn - Select Screen Mode" };

	ScreenReqHook.h_Data = NULL;
	ScreenReqHook.h_Entry = (ULONG (*)()) ScreenModeHook;
	ScreenReqHook.h_SubEntry = NULL;

	screenReq = (struct ScreenModeRequester *) AllocAslRequestTags (ASL_ScreenModeRequest,
		/*
		** initial conditions
		*/
		ASLSM_InitialDisplayID,     pref_mode,
		ASLSM_InitialDisplayWidth,  mode_width,
		ASLSM_InitialDisplayHeight, mode_height,
		/*
		** setup stuff
		*/
		ASLSM_SleepWindow,  TRUE,
		ASLSM_TitleText,    routine,
		ASLSM_MinWidth,     MINIMUM_WIDTH,
		ASLSM_MinHeight,    MINIMUM_HEIGHT,
		ASLSM_FilterFunc,   &ScreenReqHook,
		/*
		** what can the user specify
		*/
		ASLSM_DoWidth,	    TRUE,
		ASLSM_DoHeight,     TRUE,
		ASLSM_DoAutoScroll, TRUE,
		TAG_DONE);

	if (!screenReq) {
		panic ("Failed, couldn't allocate ScreenModeRequester");
	}

	if (!AslRequest (screenReq, NULL)) {
		rslt = 0;
	}
	else {
		*modeID = screenReq->sm_DisplayID;
		*height = screenReq->sm_DisplayHeight;
		*width	= screenReq->sm_DisplayWidth;
		*autoscroll = screenReq->sm_AutoScroll;
		rslt = 1;
	}

	FreeAslRequest (screenReq);

	return rslt;
}